home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Hardware / Mac OS USB DDK / Mac OS USB DDK 1.4.1 / Examples / USBSampleStorageDriver / UnitTableDriver / USB_StdCommands.c < prev    next >
Encoding:
Text File  |  2000-04-25  |  9.7 KB  |  308 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        DAM_StdCommands.c
  3.  
  4.     Contains:    All builder routines for SCSI CDBs.
  5.  
  6.     Version:    1.0
  7.  
  8.     Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  13. // All direct device access functions
  14. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  15. #include "USB_StdCommands.h"
  16.  
  17. #pragma mark --
  18. #pragma mark ATAPI/SCSI Device Commands
  19. // Expects numBytes of at least eight for write protect check
  20. OSStatus ModeSenseBuilder(IntDriveRequestPBPtr requestPB, UInt8 CommandSet, UInt8 *Buffer, UInt8 modePage, UInt8 numBytes)
  21. {
  22.     OSStatus                    status = noErr;
  23.     StorageExecuteCommandPB     *commandPB;
  24.     
  25.     commandPB = &requestPB->executePB;
  26.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  27.     BlockZero( Buffer, numBytes );
  28.  
  29.     if( CommandSet == kRBCCommand ) 
  30.     {
  31.         commandPB->cdb[0] =            kCmdModeSense6;
  32.         commandPB->cdb[1] =            0x08;                    // Disable Block Descriptors (as per RBC)
  33.         commandPB->cdb[2] =            modePage;                // Say we want the current settings for modePage
  34.         commandPB->cdb[4] =            numBytes;
  35.     }
  36.     else
  37.     {
  38.         commandPB->cdb[0] =            kCmdModeSense10;
  39.         commandPB->cdb[2] =            modePage;
  40.         commandPB->cdb[8] =            numBytes;
  41.     }
  42.     
  43.     commandPB->flags =             kStorageDataIn;                // -> Expect a data in transfer
  44.     commandPB->userBuffer =        (Ptr) Buffer;                // -> Pointer to user buffer
  45.     commandPB->expectedCount =    numBytes;                    // -> Expected number of bytes to transfer
  46.     commandPB->completionProc =    &DeviceRequestCompletion;    // -> Completion routine
  47.     
  48.     status = SendDeviceRequest(commandPB);
  49.     return status;
  50. }
  51.  
  52.  
  53. // Send Diagnostics acts as a reset on UFI devices
  54. OSStatus SendDiagnosticBuilder( IntDriveRequestPBPtr requestPB )
  55. {
  56.     OSStatus                    status = noErr;
  57.     StorageExecuteCommandPB     *commandPB;
  58.     
  59.     commandPB = &requestPB->executePB;
  60.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  61.  
  62.     commandPB->cdb[0] =            kCmdSendDiagnostic;
  63.     commandPB->cdb[1] =            0x04;
  64. #if 0
  65.     commandPB->cdb[2] =            0xFF;
  66.     commandPB->cdb[3] =            0xFF;
  67.     commandPB->cdb[4] =            0xFF;
  68.     commandPB->cdb[5] =            0xFF;
  69.     commandPB->cdb[6] =            0xFF;
  70.     commandPB->cdb[7] =            0xFF;
  71.     commandPB->cdb[8] =            0xFF;
  72.     commandPB->cdb[9] =            0xFF;
  73.     commandPB->cdb[10] =        0xFF;
  74.     commandPB->cdb[11] =        0xFF;
  75. #endif
  76.     commandPB->flags =             kStorageNoData;                        // -> Expect a data in transfer
  77.     commandPB->userBuffer =        nil;                                // -> Pointer to user buffer
  78.     commandPB->expectedCount =    0x00;                                // -> Expected number of bytes to transfer
  79.     commandPB->completionProc =    &DeviceRequestCompletion;            // -> Completion routine
  80.         
  81.     status = SendDeviceRequest(commandPB);
  82.     return status;
  83. }
  84.  
  85.  
  86. // Expects no buffer
  87. OSStatus TestUnitReadyBuilder( IntDriveRequestPBPtr requestPB )
  88. {
  89.     OSStatus                    status = noErr;
  90.     StorageExecuteCommandPB     *commandPB;
  91.     
  92.     commandPB = &requestPB->executePB;
  93.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  94.  
  95.     commandPB->flags =             kStorageNoData;    
  96.     commandPB->completionProc =    &DeviceRequestCompletion;
  97.     
  98.     status = SendDeviceRequest(commandPB);
  99.     return status;
  100. }
  101.  
  102. OSStatus RequestSenseBuilder( IntDriveRequestPBPtr requestPB, Ptr senseData )
  103. {
  104.     OSStatus                    status = noErr;
  105.     StorageExecuteCommandPB     *commandPB;
  106.  
  107.     commandPB = &requestPB->executePB;
  108.  
  109.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  110.     BlockZero( senseData, kSenseStandardDataSize);
  111.     
  112.     commandPB->cdb[0] =            kCmdRequestSense;
  113.     commandPB->cdb[4] =            kSenseStandardDataSize;
  114.     commandPB->flags =             kStorageDataIn;                    // -> Expect a data in transfer
  115.     commandPB->userBuffer =        senseData;                        // -> Pointer to user buffer
  116.     commandPB->expectedCount =    kSenseStandardDataSize;            // -> Expected number of bytes to transfer
  117.     commandPB->completionProc =    &DeviceRequestCompletion;        // -> Completion routine
  118.     
  119.  
  120.     status = SendDeviceRequest(commandPB);    
  121.     
  122.     return status;
  123. }
  124.  
  125. // Examine the data returned by Request Sense and if valid data was returned, but
  126. // fewer than 18 bytes, fix it so that it looks like all data was returned.
  127. // If no error occurred on the command, just return without doing anything.
  128. void FixRequestSenseData( IntDriveRequestPBPtr requestPB )
  129. {
  130.     if ( requestPB->status != noErr )
  131.     {
  132.         if ( requestPB->executePB.actualCount >= 13 )
  133.         {
  134.             // Enough data was returned to have a valid ASC and ASCQ
  135.             // go ahead and pad the data.
  136.             BlockZero((Ptr) (((UInt32) requestPB->executePB.userBuffer) + requestPB->executePB.actualCount),
  137.                                 requestPB->executePB.expectedCount-requestPB->executePB.actualCount);
  138.             
  139.             // Update the actual count field
  140.             requestPB->executePB.actualCount = requestPB->executePB.expectedCount;
  141.             
  142.             // Act like no error occurred
  143.             requestPB->status = noErr;
  144.         }
  145.     }
  146. }
  147.  
  148. // Expects buffer of at least InqDataLength
  149. OSStatus InquiryBuilder(IntDriveRequestPBPtr requestPB, UInt8 *Buffer, UInt8 InqDataLength)
  150. {
  151.     OSStatus                    status = noErr;
  152.     StorageExecuteCommandPB     *commandPB;
  153.     
  154.     commandPB = &requestPB->executePB;
  155.  
  156.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  157.     BlockZero( Buffer, InqDataLength);
  158.     
  159.     commandPB->cdb[0] =            kCmdInquiry;
  160.     commandPB->cdb[4] =            InqDataLength;
  161.     commandPB->flags =             kStorageDataIn;                // -> Expect a data in transfer
  162.     commandPB->userBuffer =        (Ptr) Buffer;                // -> Pointer to user buffer
  163.     commandPB->expectedCount =    InqDataLength;                // -> Expected number of bytes to transfer
  164.     commandPB->completionProc =    &DeviceRequestCompletion;    // -> Completion routine
  165.     
  166.     status = SendDeviceRequest(commandPB);    
  167.     return status;
  168. }
  169.  
  170. // Expects a buffer of size ReadCapacityData
  171. OSStatus GetMediaGeometryBuilder(IntDriveRequestPBPtr requestPB, ReadCapacityData *getGeometry)
  172. {
  173.     OSStatus                    status = noErr;
  174.     StorageExecuteCommandPB     *commandPB;
  175.  
  176.     commandPB = &requestPB->executePB;
  177.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  178.  
  179.     getGeometry->TotalBlocksOnMedia = 0;
  180.     getGeometry->BlockLengthInBytes = 0;
  181.     
  182.     commandPB->cdb[0] =            kCmdReadCapacity;
  183.     commandPB->flags =             kStorageDataIn;                // -> Expect a data in transfer
  184.     commandPB->userBuffer =        (Ptr) getGeometry;            // -> Pointer to user buffer
  185.     commandPB->expectedCount =    sizeof(ReadCapacityData);    // -> Expected number of bytes to transfer
  186.     commandPB->completionProc =    &DeviceRequestCompletion;    // -> Completion routine
  187.     
  188.     status = SendDeviceRequest(commandPB);
  189.     return status;
  190. }
  191.  
  192.  
  193. // Expects a buffer of at least 0x0C (12) 
  194. OSStatus ReadFormatCapacityBuilder(IntDriveRequestPBPtr requestPB, UInt8 *Buffer, UInt8 numBytes)
  195. {
  196.     OSStatus                    status = noErr;
  197.     StorageExecuteCommandPB     *commandPB;
  198.     
  199.     commandPB = &requestPB->executePB;
  200.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  201.  
  202.     commandPB->cdb[0] =            kCmdReadFormatCapacities;
  203.     commandPB->cdb[7] =            0;
  204.     commandPB->cdb[8] =            numBytes;
  205.     commandPB->flags =             kStorageDataIn;                // -> Expect a data in transfer
  206.     commandPB->userBuffer =        (Ptr) Buffer;                // -> Pointer to user buffer
  207.     commandPB->expectedCount =    numBytes;                    // -> Expected number of bytes to transfer
  208.     commandPB->completionProc =    &DeviceRequestCompletion;    // -> Completion routine
  209.     
  210.     status = SendDeviceRequest(commandPB);
  211.     return status;
  212. }
  213.  
  214. OSStatus FormatFloppyTrackBuilder( IntDriveRequestPBPtr requestPB, UInt8 *Buffer, UInt32 FormatCapacity, UInt16 blockSize, UInt8 TrackNum, UInt8 Side)
  215. {
  216.     OSStatus                    status = noErr;
  217.     StorageExecuteCommandPB     *commandPB;
  218.     
  219.     commandPB = &requestPB->executePB;
  220.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  221.  
  222.     BlockZero( Buffer, 0x0C);
  223.  
  224.     // Set up the data going out
  225.     // First set up the Defect List Header
  226.     Buffer[0] = 0;
  227.     Buffer[1] = 0x80 | 0x20 | 0x10 | Side;
  228.     Buffer[2] = 0;
  229.     Buffer[3] = 0x08;
  230.  
  231.     *((UInt32 *) &Buffer[4]) = FormatCapacity;
  232.     *((UInt16 *) &Buffer[10]) = blockSize;
  233.     
  234.     commandPB->cdb[0] =            kCmdFormat;
  235.     commandPB->cdb[1] =            0x17;
  236.     commandPB->cdb[2] =            TrackNum;
  237.     commandPB->cdb[8] =            0x0C;
  238.     commandPB->flags =             kStorageDataOut | kStorageUseCommandCompletionInt;    // -> Expect a data out transfer and wait for interrupt
  239.     commandPB->userBuffer =        (Ptr) Buffer;                                        // -> Pointer to user buffer
  240.     commandPB->expectedCount =    0x0C;                                                // -> Expected number of bytes to transfer
  241.     commandPB->completionProc =    &DeviceRequestCompletion;                            // -> Completion routine
  242.  
  243.     status = SendDeviceRequest(commandPB);
  244.     return status;
  245. }
  246.  
  247.  
  248. OSStatus StartStopEjectCartridgeBuilder(IntDriveRequestPBPtr requestPB, Boolean StartDrive, Boolean doEject)
  249. {
  250.     OSStatus                    status = noErr;
  251.     StorageExecuteCommandPB     *commandPB;
  252.     
  253.     commandPB = &requestPB->executePB;
  254.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  255.     
  256.     commandPB->cdb[0] =            kCmdStartStopUnit;
  257.     if( doEject )
  258.     {
  259.         commandPB->cdb[4] =            0x02;                        // Unload the Media
  260.     }
  261.     else if ( StartDrive )
  262.     {
  263.         commandPB->cdb[4] =            0x01;                        // Start the Drive
  264.     }
  265.     else
  266.     {
  267.         commandPB->cdb[4] =            0x00;                        // Stop the drive, but don't eject
  268.     }
  269.     
  270.     
  271.     commandPB->flags =             kStorageNoData;                    // -> Expect no data transfer
  272.     commandPB->userBuffer =        nil;                            // -> Pointer to user buffer
  273.     commandPB->expectedCount =    0;                                // -> Expected number of bytes to transfer
  274.     commandPB->completionProc =    (StorageClassCompletionProcPtr) &DeviceRequestCompletion;    // -> Completion routine
  275.     
  276.     status = SendDeviceRequest(commandPB);
  277.     return status;
  278. }
  279.  
  280.  
  281. OSStatus PreventAllowRemovalBuilder(IntDriveRequestPBPtr requestPB, Boolean preventRemoval )
  282. {
  283.     OSStatus                    status = noErr;
  284.     StorageExecuteCommandPB     *commandPB;
  285.         
  286.     commandPB = &requestPB->executePB;
  287.     BlockZero( commandPB, sizeof(StorageExecuteCommandPB));
  288.     
  289.     commandPB->cdb[0] =            kCmdPreventAllowRemoval;
  290.     if ( preventRemoval == true )
  291.     {
  292.         commandPB->cdb[4] =            0x01;            // Prevent Media Removal
  293.     }
  294.     else
  295.     {
  296.         commandPB->cdb[4] =            0x00;            // Allow Media Removal
  297.     }
  298.     
  299.     commandPB->flags =             kStorageNoData;        // -> Expect no data transfer
  300.     commandPB->userBuffer =        nil;                // -> Pointer to user buffer
  301.     commandPB->expectedCount =    0;                    // -> Expected number of bytes to transfer
  302.     commandPB->completionProc =    &DeviceRequestCompletion;    // -> Completion routine
  303.     
  304.     status = SendDeviceRequest(commandPB);
  305.     return status;
  306. }
  307.  
  308.